package com.syjy.tunnelworker.senders.iml;

import com.syjy.DataExchangeException;
import com.syjy.container.ProtocolDataContainer;
import com.syjy.tunnelinfo.DataPoint;
import com.syjy.tunnelinfo.TunnelStatus;
import com.syjy.tunnelinfo.sendertunnelinfo.SenderModbusRtuTunnelInfo;
import com.syjy.tunnelworker.BaseProtocolTunnel;
import com.syjy.tunnelworker.senders.DataSenderInterface;
import com.syjy.tunnelworker.workassist.SingleThreadPoolExecutorUtil;
import wei.yigulu.modbus.domain.datatype.BooleanModbusDataInRegister;
import wei.yigulu.modbus.domain.datatype.ModbusDataTypeEnum;
import wei.yigulu.modbus.domain.datatype.NumericModbusData;
import wei.yigulu.modbus.netty.ModbusRtuSlaverBuilder;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * modbus Rtu 的数据转发通道
 *
 * @author: xiuwei
 * @version:
 */

public class ModbusRtuDataSender extends AbstractModbusDataSender<SenderModbusRtuTunnelInfo, ModbusRtuSlaverBuilder> implements DataSenderInterface {


	/**
	 * 顶层的构造方法
	 *
	 * @param tunnelInfo 通道信息
	 */
	public ModbusRtuDataSender(SenderModbusRtuTunnelInfo tunnelInfo) {
		super(tunnelInfo);
	}

	@Override
	public ModbusRtuDataSender buildTunnel() throws DataExchangeException {
		protocolBuilder = new ModbusRtuSlaverBuilder(this.tunnelInfo.getSerialName());
		protocolBuilder.setBaudRate(tunnelInfo.getBaudRate());
		protocolBuilder.setDataBits(tunnelInfo.getDataBits());
		protocolBuilder.setStopBits(tunnelInfo.getStopBits());
		protocolBuilder.setParity(tunnelInfo.getParity());
		setSlaveId(this.tunnelInfo.getSlaveId());
		setModbusSlaveDataContainer(protocolBuilder.getModbusSlaveDataContainer());
		if (this.tunnelInfo.getFunctionCode() == 1 || this.tunnelInfo.getFunctionCode() == 2) {
			setFunctionFlag(0);
		} else {
			setFunctionFlag(1);
		}
		protocolBuilder.setLog(this.log);
		log.info("成功创建ModbusRTUSlaver通道对象：{}", this.tunnelInfo.getTunnelName());
		setTunnelStatus(TunnelStatus.BUILT);
		protocolTunnelContainer.addTunnel(this);
		parseGatherDataPoint();
		return this;
	}


	@Override
	public ModbusRtuDataSender startTunnel() throws DataExchangeException {
		log.info("modbus RTU slaver {} 通道开始连接", getTunnelInfo().getTunnelName());
		protocolTunnelContainer.addUpdateDateTask(this);
		try {
			SingleThreadPoolExecutorUtil.executeBySingleThreadExecutor(() -> {
				try {
					this.protocolBuilder.create();
					log.error("Modbus Rtu slaver  创建通道失败");
					setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
				} catch (Exception e) {
					log.error("Modbus Rtu slaver  创建通道失败", e);
					setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
				}
			});
		} catch (Exception e) {
			log.error("Modbus Rtu slaver 创建通道失败", e);
			setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
			throw new DataExchangeException(10007, "Modbus Rtu slaver创建通道失败");
		}
		if (!TunnelStatus.LISTENSERIALFAIL.equals(getTunnelStatus())) {
			setTunnelStatus(TunnelStatus.LISTENSERIALSUCCESS);
		}
		return this;
	}


	@Override
	public BaseProtocolTunnel tunnelStop() throws DataExchangeException {
		if (this.protocolBuilder != null) {
			this.protocolBuilder.stop();
		}
		log.info("关闭 Modbus Rtu slaver 通道 {}", this.tunnelInfo.getTunnelName());
		return super.tunnelStop();
	}

}
